"use strict";

// 检测 setTimeout 函数的使用
// 目的: 每间隔50ms执行某方法(当前是打印Tick)
// 当CPU使用率上升时, 开始不稳定

// 解决方案思路: 
// 1. 是否能在linux多核心, 把本进程指定到某一个CPU上,
// 并且指定该核心专为本进程服务, 减少中断和本CPU的占用
// 2. 换成Go语言试一试?

function Server() {
    this.time = 0;

    this.counter = 0;
    this.tock = 0;
}

Server.prototype.start = function () {
    this.time = new Date().valueOf();
    this.counter = 0;
    this.tock = new Date().valueOf();
//    this.update();
//    this.timeout();
   this.cycle();
   // this.interval();
   this.tick();
};

/**
 * 方案1: 1ms执行一次逻辑(实际多少毫秒看系统多久能循环到)
 * 然后计算本次与上次ms数差值, 累加超过50就执行逻辑
 *
 * cpu占用1.7%
 * 内存占用1.6%
 */
Server.prototype.update = function () {
    setTimeout(this.update.bind(this), 1);

    var time = new Date().valueOf();

    var passedTick = time - this.tock;
    if (passedTick <= 0) return; //console.log("Tock " + (passedTick));

    this.counter += passedTick;
    this.tock = time;

    if (this.counter >= 50) {
        this.counter = 0;
        var delta = time - this.time;
        if (Math.abs(delta - 50) > 5) console.log(passedTick + " " + delta);
        this.time = time;
    }
};

/**
 * 方案2: setTimeout 50ms执行一次逻辑
 *
 * cpu占用2%
 * 内存占用1.9%
 */
Server.prototype.timeout = function () {
    setTimeout(this.onLoop.bind(this), 50);

    var time = new Date().valueOf();

    var delta = time - this.time;
    if (Math.abs(delta - 50) > 5) console.log(delta);
    this.time = time;
};

/**
 * 方案3: 无限死循环执行逻辑, 依据时间判断条件执行逻辑
 *
 * cpu占用90%+
 * 内存占用1.8%
 */
Server.prototype.cycle = function () {
    for (; ;) {
        if (this.time < 0) {
            return;
        }

        var time = new Date().valueOf();

        var delta = time - this.time;
        if (delta >= 50) {
            if (Math.abs(delta - 50) > 5) console.log(delta);
            this.time = time;
        }
    }
};

/**
 * 方案4: setInterval 50ms执行一次逻辑
 *
 * cpu占用0.3%
 * 内存占用1.6%
 */
Server.prototype.interval = function () {
    setInterval(function () {
        var time = new Date().valueOf();

        var delta = time - this.time;
        if (Math.abs(delta - 50) > 5) console.log(delta);
        this.time = time;
    }.bind(this), 50);
};

/**
 * 方案5: 无限死循环调用自身, 不满足时将自身抛入nextTick
 *
 * cpu占用93%
 * 内存占用4.7%
 */
Server.prototype.tick = function () {
    var time = new Date().valueOf();

    var delta = time - this.time;
    if (delta < 50) return process.nextTick(this.tick.bind(this));

    if (Math.abs(delta - 50) > 5) console.log(delta);
    this.time = time;
    this.tick();
};

var server = new Server();
server.start();
